#pragma once


#include <iostream>
#include "Log.hpp"
#include "Connection.hpp"
#include "Reactor.hpp"

using namespace log_ns;
const static size_t buffersize = 512;

class HandlerConnection
{
private:
public:
    HandlerConnection(handler_t process)
        : _process(process)
    {}

    void HandlerRecver(Connection* conn)
    {
        errno = 0;
        while (true)
        {
            char buffer[buffersize];
            ssize_t n = ::recv(conn->GetSockfd(), buffer, sizeof(buffer) - 1, 0);
            if (n > 0)
            {
                buffer[n] = 0;
                conn->AppendInBuffer(buffer);
            }
            else
            {
                if (errno == EWOULDBLOCK)
                {
                    break;
                }
                else if (errno == EINTR)
                {
                    continue;
                }
                else
                {
                    conn->HandlerExcepter()(conn);
                    return;
                }
            }
        }
        // 至此一定是读取完毕 
        std::cout << conn->GetSockfd() << " : " << std::endl << conn->GetInbuffer() << std::endl;

        _process(conn);
        // 在这里是将读取的数据直接进行处理（PackageParse::Execute） 
        // 但可以将该任务交给线程池啊，让线程池进行处理 
        // 这样就可以将业务的控制权交给线程池 
    }

    void HandlerSender(Connection* conn)
    {
        errno = 0;
        while (true)
        {
            ssize_t n = ::send(conn->GetSockfd(), conn->GetOutbuffer().c_str(), conn->GetOutbuffer().size(), 0);
            if (n > 0)
            {
                conn->DiscardOutbuffer(n);
                if (conn->GetOutbuffer().empty()) break;
            }
            else if (n == 0)
            {
                LOG(WARNING, "No data sent?\n");
                break;
            }
            else
            {
                if (errno == EWOULDBLOCK)
                {
                    break;
                }
                else if (errno == EINTR)
                {
                    continue;
                }
                else
                {
                    conn->HandlerExcepter()(conn);
                    return;
                }
            }
        }
        // 至此可能为发送条件不满足 && 缓冲区内还有数据 
        if (!conn->GetOutbuffer().empty())
        {
            // 开启对写事件的关心 
            conn->GetReactor()->EnableConnectionReadWrite(conn->GetSockfd(), true, true);
        }
        else 
        {
            conn->GetReactor()->EnableConnectionReadWrite(conn->GetSockfd(), true, false);
        }
    }

    void HandlerExcepter(Connection* conn)
    {
        // 代码里的所有异常，全部堵在这里
        // 删除连接
        conn->GetReactor()->DelConnection(conn->GetSockfd());
    }

private:
    handler_t _process;
};



